package controlsystem;

import java.util.Date;
import java.util.Iterator;
import java.util.ArrayList;

import managesystem.Student;
import tracksystem.Activity;
import tracksystem.SchoolActivity;

/**
 * @author Stijn Hoskens
 * Deze klasse controleert na elke activity die de student ingeeft of hij een welbepaalde badge verdient
 * Die badge haalt hij uit een array met badges.
 */

public class BadgeController {
	
	/**
	 * Constructor voor een BadgeController-object, de currStudent wordt ingesteld en zijn reeds behaalde
	 * badges worden al opgeslagen in studentsBadges (een array zodat wanneer de student in aanmerking komt
	 * voor een badge, hij gemakkelijk kan vergelijken, badges[i] == studentsBadges[i]? of hij die badge
	 * al bezit. De array met badges wordt geladen.
	 */
	public BadgeController()
	{
		
	}
	
	/**
	 * Deze methode wordt uitgevoerd elke keer als een activity wordt ingevoerd in het systeem. 
	 * Als het een schoolactivity betreft, gaat men heel de lijst met activities af en worden het totaal aantal
	 * uren en de pagina's van het desbetreffende vak gelezen en kan men nakijken of de student in aanmerking
	 * komt voor een badge.
	 * @param activity
	 */
	public static ArrayList<Badge> checkBadge(Course course, Student currStud)
	{
		ArrayList<Badge> latestBadges = new ArrayList<Badge>();
		String courseName = course.getName();
		long totalMSecs = 0;
		int amountOfPages = 0;
		long studyPointsMSecs = course.getStudyPoints()*99000000;
		Date currDate = new Date();
		Iterator<SchoolActivity> it = getSchoolAct(currStud).iterator();
		while(it.hasNext())
		{
			SchoolActivity sa = it.next();
			if(sa.getCourse().getName().equals(courseName))
			{
					totalMSecs += sa.getDuration();
					amountOfPages += sa.getPages();
			}
		}
		checkIfBadgeStudyPoints(0, studyPointsMSecs/10, totalMSecs, currDate, courseName, currStud, latestBadges);
		checkIfBadgeStudyPoints(1, studyPointsMSecs/4, totalMSecs, currDate, courseName, currStud, latestBadges);
		checkIfBadgeStudyPoints(2, studyPointsMSecs/2, totalMSecs, currDate, courseName, currStud, latestBadges);
		checkIfBadgeStudyPoints(3, 3*studyPointsMSecs/4, totalMSecs, currDate, courseName, currStud, latestBadges);
		checkIfBadgeStudyPoints(4, 9*studyPointsMSecs/10, totalMSecs, currDate, courseName, currStud, latestBadges);
		checkIfBadgeStudyPoints(5, studyPointsMSecs, totalMSecs, currDate, courseName, currStud, latestBadges);
		checkIfBadgePages(6, 50, amountOfPages, currDate, courseName, currStud, latestBadges);
		checkIfBadgePages(7, 100, amountOfPages, currDate, courseName, currStud, latestBadges);
		checkIfBadgePages(8, 200, amountOfPages, currDate, courseName, currStud, latestBadges);
		checkIfBadgePages(9, 300, amountOfPages, currDate, courseName, currStud, latestBadges);
		return latestBadges;
	}
	
	/**
	 * Hierin worden de verschillende badges geladen, met badges[0] t.e.m. badges[5] badges ivm. studiepunten
	 * en badges[6] t.e.m. badges[9] badges ivm. het aantal pagina's geleerd.
	 */
	private static Badge[] loadBadges()
	{
		Badge[] badges = new Badge[10];
		badges[0] = new Badge("10% of studyPoints", "Congratulations, now you have studied 10% of the estimated amount of hours!", "aantaluur", 10);
		badges[1] = new Badge("25% of studyPoints", "Awesome, now you have studied 25% of the estimated amount of hours!", "aantaluur", 25);
		badges[2] = new Badge("50% of studyPoints", "Congratulations, now you have studied 50% of the estimated amount of hours!", "aantaluur", 50);
		badges[3] = new Badge("75% of studyPoints", "Awesome, now you have studied 75% of the estimated amount of hours!", "aantaluur", 75);
		badges[4] = new Badge("90% of studyPoints", "Congratulations, now you have studied 90% of the estimated amount of hours! You're almost ready for the exam.", "aantaluur", 90);
		badges[5] = new Badge("100% of studyPoints", "Awesome, now you have studied the full 100% of the estimated amount of hours! You should be ready by now.", "aantaluur", 100);
		badges[6] = new Badge("50 pages studied", "Nice! You've done the first 50 pages.", "aantalpaginas", 50);
		badges[7] = new Badge("100 pages studied", "Cool! The first 100 pages are done", "aantalpaginas", 100);
		badges[8] = new Badge("200 pages studied", "Awesome! You've done the first 200 pages.", "aantalpaginas", 200);
		badges[9] = new Badge("300 pages studied", "Congratulations, the first 300 pages are done.", "aantalpaginas", 300);
		return badges;
	}
	
	/**
	 * Als totalMSecs (het aantal milliseconde dat de student aan dat vak reeds geleerd heeft) groter of gelijk is
	 * aan studyPointsMSecs (een deel van het aantal milliseconden dat je aan dat vak zou moeten spenderen, SP*27.5*60*60*1000)
	 * dan wordt de lijst met badges die de student al behaald heeft afgegaan en gekeken of de badge met die
	 * courseName & Name al in de lijst zit, zoniet wordt de badge aan de student gegeven.
	 * @param i de plaats van de badge in de lijst badges, er wordt gecontroleerd of de student badges[i] al heeft voor dat vak
	 * @param studyPointsMSecs een deel van het aantal milliseconden dat je aan dat vak zou moeten spenderen, SP*27.5*60 
	 * @param totalMSecs het aantal milliseconden dat de student aan dat vak reeds geleerd heeft
	 * @param date de datum wanneer de badge behaald is
	 * @param courseName de naam van het vak
	 */
	private static void checkIfBadgeStudyPoints(int i, long studyPointsMSecs, long totalMSecs, Date date, String courseName, Student currStud, ArrayList<Badge> achievedBadges)
	{
		if(totalMSecs >= studyPointsMSecs)
		{
			boolean found = false;
			Badge[] badges = loadBadges();
			Iterator<Badge> it = currStud.getBadges().iterator();
			while(it.hasNext() && !found)
			{
				Badge b = it.next();
				if(b.getCourseName().equals(courseName) && b.getName().equals(badges[i].getName()))
				{
					found = true;
				}
			}
			if(!found)
			{
				Badge achievedBadge = badges[i];
				achievedBadge.setDate(date);
				achievedBadge.setCourseName(courseName);
				currStud.addBadge(achievedBadge);
				achievedBadges.add(achievedBadge);
			}
		}
	}
	
	/**
	 * Als pagesStudied (het aantal pagina's dat de student reeds geleerd heeft) groter of gelijk is
	 * aan pages (een vooropgesteld doel, bvb. 50, 100, 200,... paginas)
	 * dan wordt de lijst met badges die de student al behaald heeft afgegaan en gekeken of de badge met die
	 * courseName & Name al in de lijst zit, zoniet wordt de badge aan de student gegeven.
	 * @param i de plaats van de badge in de lijst badges, er wordt gecontroleerd of de student badges[i] al heeft voor dat vak
	 * @param pages een vooropgesteld doel, bvb. 50, 100, 200,... paginas
	 * @param pagesStudied het aantal pagina's dat de student reeds geleerd heeft
	 * @param date de datum wanneer de badge behaald is
	 * @param courseName de naam van het vak
	 */
	private static void checkIfBadgePages(int i, int pages, int pagesStudied, Date date, String courseName, Student currStud, ArrayList<Badge> achievedBadges)
	{
		if(pagesStudied >= pages)
		{
			boolean found = false;
			Badge[] badges = loadBadges();
			Iterator<Badge> it = currStud.getBadges().iterator();
			while(it.hasNext() && !found)
			{
				Badge b = it.next();
				if(b.getCourseName().equals(courseName) && b.getName().equals(badges[i].getName()))
				{
					found = true;
				}
			}
			if(!found)
			{
				Badge achievedBadge = badges[i];
				achievedBadge.setDate(date);
				achievedBadge.setCourseName(courseName);
				currStud.addBadge(achievedBadge);
				achievedBadges.add(achievedBadge);
			}
		}
	}
	
	private static ArrayList<SchoolActivity> getSchoolAct(Student currStud)
	{
		ArrayList<SchoolActivity> schoolActivities = new ArrayList<SchoolActivity>();
		Iterator<Activity> it = currStud.getAct().iterator();
		while(it.hasNext()) {
			Activity a = it.next();
			if(a instanceof SchoolActivity) {
				schoolActivities.add((SchoolActivity) a);
			}
		}
		return schoolActivities;
	}
}
